﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Rex.Service.Core.Results;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Rex.Workflow.Filters
{
    /// <summary>
    /// 后台管理结果过滤
    /// </summary>
    public class BmResultFilter : ResultFilterAttribute
    {
        public override async void OnResultExecuting(ResultExecutingContext context)
        {
            if (IsHandleResult(context))
            {
                // 如果结果已经是 BmResult 类型，则无需进行包装
                if (context.Result is ObjectResult objectResult && objectResult.Value is BmResult)
                {
                    base.OnResultExecuting(context);
                    return;
                }

                if (context.Result is ObjectResult)
                {
                    #region 验证是否有错误

                    List<string> errMsgList = new List<string>();
                    foreach (var key in context.ModelState.Keys)
                    {
                        var errVal = context.ModelState[key];
                        string errMsg = string.Empty;
                        foreach (var error in errVal?.Errors)
                        {
                            string eMsg = error.Exception == null ? error.ErrorMessage : error.Exception.Message;
                            errMsg += $"{eMsg} ";
                        }
                        if (!errMsg.IsNullOrWhiteSpace())
                        {
                            errMsgList.Add(errMsg);
                        }
                    }

                    #endregion 验证是否有错误

                    #region 包装返回结果

                    ObjectResult oResult = context.Result as ObjectResult;
                    var apiResult = new BmResult();
                    if (errMsgList.Count < 1)
                    {
                        apiResult.SetSuccess(oResult?.Value);
                    }
                    else
                    {
                        apiResult.SetFail($"您共有 {errMsgList.Count} 个错误：{string.Join(";", errMsgList)}");
                    }

                    #endregion 包装返回结果

                    context.Result = new JsonResult(apiResult);
                }
            }
            base.OnResultExecuting(context);
        }

        /// <summary>
        /// 是否需要处理
        /// </summary>
        /// <returns></returns>
        private bool IsHandleResult(ResultExecutingContext context)
        {
            if (context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(BmResultAttribute), true).Any())
            {
                return true;
            }
            if (context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(BmResultAttribute), true).Any())
            {
                return true;
            }
            return false;
        }
    }
}